home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / RMLIB.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  11KB  |  593 lines

  1. /*****************************************************************************
  2.  * FILE: rmlib.c                                 *
  3.  *                                         *
  4.  * DESC:                                     *
  5.  *    - Interface to Real Mode calls                         *
  6.  *                                         *
  7.  * Copyright (C) 1993,1994                             *
  8.  *    Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld             *
  9.  *    email: rainer@mathematik.uni-bielefeld.de                 *
  10.  *                                         *
  11.  *****************************************************************************/
  12.  
  13. #include "DPMI.H"
  14. #include "PROCESS.H"
  15. #include "START32.H"
  16. #include "CDOSX32.H"
  17. #include "RMLIB.H"
  18. #include "DOSERRNO.H"
  19.  
  20. #define LV_WORD *(WORD *)&
  21.  
  22. unsigned rm_bios_read_keybrd(unsigned mode)
  23. {
  24.     TRANSLATION tr;
  25.     unsigned key;
  26.  
  27.     LV_WORD tr.eax = mode << 8;
  28.     tr.sp = tr.ss = 0;
  29.     tr.flags = 0x3200;
  30.     tr.cs = cs16real;
  31.     tr.ds = cs16real;
  32.     SimulateRMint(0x16, 0, 0, &tr);
  33.     key = (unsigned) (tr.eax & 0xFFFF);
  34.  
  35.     if ((tr.flags & 64) && (mode == 0x01 || mode == 0x11))
  36.     return 0;
  37.     else
  38.     return key;
  39. }
  40.  
  41. #ifdef __EMX__
  42. #define SET_SEG_OFF(pointer, seg, off) \
  43.     { seg = (((unsigned) (pointer) & ~0xFFF) >> 4) + ds16real; \
  44.     off = (unsigned) (pointer) & 0xFFF; }
  45. #else                /* 16 bit compiler */
  46. #define SET_SEG_OFF(pointer, seg, off) \
  47.     { seg = ds16real; off = (WORD) (pointer) ;}
  48. #endif
  49.  
  50. #ifdef __EMX__
  51. #define SET_SEG_OFF_64(pointer, seg, off) \
  52.     { seg = (((unsigned) (pointer) & ~0xFFFF) >> 4) + ds16real; \
  53.     off = (unsigned) (pointer) & 0xFFFF; }
  54.  
  55. #else                /* 16 bit compiler */
  56. #define SET_SEG_OFF_64(pointer, seg, off) \
  57.     { seg = ds16real; off = (WORD) (pointer) ;}
  58. #endif
  59.  
  60. unsigned emx_errno;
  61.  
  62. static int call_rm_dos(TRANSLATION *ts)
  63. {
  64.     ts->flags = 0x3200;
  65.     ts->cs = cs16real;
  66.  
  67.     SET_SEG_OFF_64(real_mode_stack, ts->ss, ts->sp);
  68.  
  69.     /* DPMI-Call to Real-Mode DOS */
  70.     SimulateRMint(0x21, 0, 0, ts);
  71.  
  72.     /* return Carry-bit */
  73.     if (ts->flags & 1) {
  74.     _doserrno = (unsigned) ts->eax & 0xFFFF;
  75.     emx_errno = doserror_to_errno(_doserrno);
  76.     return -1;
  77.     } else
  78.     return (int) (ts->eax & 0xFFFF);
  79. }
  80.  
  81. /* ********** DISK OPERATIONS ********** */
  82.  
  83. /*
  84. ** AH = 0x0E
  85. ** DL = drive (a=0,b=1,c=2)
  86. ** return: AL max drive
  87. */
  88. int rm_setdrive(WORD drive)
  89. {
  90.     TRANSLATION ts;
  91.  
  92.     LV_WORD ts.eax = 0x0E00;
  93.     LV_WORD ts.edx = drive;
  94.     return (call_rm_dos(&ts) & 0xFF);
  95. }
  96.  
  97. /*
  98. ** AH = 0x19
  99. ** return: AL this drive (a=0,b=1,c=2)
  100. */
  101. int rm_getdrive(void)
  102. {
  103.     TRANSLATION ts;
  104.  
  105.     LV_WORD ts.eax = 0x1900;
  106.     return (call_rm_dos(&ts) & 0xFF);
  107. }
  108.  
  109. /*
  110. ** AH = 0x1A
  111. ** DS:DX dta address
  112. */
  113. void rm_setdta(void *buf)
  114. {
  115.     TRANSLATION ts;
  116.  
  117.     LV_WORD ts.eax = 0x1A00;
  118.     SET_SEG_OFF(buf, ts.ds, ts.edx);
  119.     call_rm_dos(&ts);
  120. }
  121.  
  122. /* ********** DATE/TIME OPERATIONS ********** */
  123.  
  124. /*
  125. ** AH = 0x2A
  126. ** return: CX=year DX=month/day
  127. */
  128. void rm_getdate(struct dos_date * dd)
  129. {
  130.     TRANSLATION ts;
  131.  
  132.     LV_WORD ts.eax = 0x2A00;
  133.     call_rm_dos(&ts);
  134.     dd->ddate_year = (WORD) ts.ecx;
  135.     dd->ddate_month = (BYTE) ((WORD) ts.edx >> 8);
  136.     dd->ddate_day = (BYTE) ts.edx;
  137.     dd->ddate_dayofweek = (BYTE) ts.eax;
  138. }
  139.  
  140. /*
  141. ** AH = 0x2B
  142. ** CX = year
  143. ** DX = month/day
  144. */
  145. int rm_setdate(struct dos_date * dd)
  146. {
  147.     TRANSLATION ts;
  148.  
  149.     LV_WORD ts.eax = 0x2B00;
  150.     LV_WORD ts.ecx = (WORD) dd->ddate_year;
  151.     LV_WORD ts.edx = ((WORD) dd->ddate_month << 8) | dd->ddate_day;
  152.     call_rm_dos(&ts);
  153.     if ((ts.eax & 0xFF) == 0xFF)
  154.     return -1;
  155.     else
  156.     return 0;
  157. }
  158.  
  159. /*
  160. ** AH = 0x2C
  161. ** return CX=hour/min DX=sec/hsec
  162. */
  163. void rm_gettime(struct dos_time * dt)
  164. {
  165.     TRANSLATION ts;
  166.  
  167.     LV_WORD ts.eax = 0x2C00;
  168.     call_rm_dos(&ts);
  169.     dt->dtime_hour = (BYTE) ((WORD) ts.ecx >> 8);
  170.     dt->dtime_minutes = (BYTE) ts.ecx;
  171.     dt->dtime_seconds = (BYTE) ((WORD) ts.edx >> 8);
  172.     dt->dtime_hsec = (BYTE) ts.edx;
  173. }
  174.  
  175. /*
  176. ** AH = 0x2D
  177. ** CX = hour/min
  178. ** DX = sec/hsec
  179. */
  180. int rm_settime(struct dos_time * dt)
  181. {
  182.     TRANSLATION ts;
  183.  
  184.     LV_WORD ts.eax = 0x2D00;
  185.     LV_WORD ts.ecx = ((WORD) dt->dtime_hour << 8) | dt->dtime_minutes;
  186.     LV_WORD ts.edx = ((WORD) dt->dtime_seconds << 8) | dt->dtime_hsec;
  187.     call_rm_dos(&ts);
  188.     if ((ts.eax & 0xFF) == 0xFF)
  189.     return -1;
  190.     else
  191.     return 0;
  192. }
  193.  
  194. /* ********** DIRECTORY OPERATIONS ********** */
  195.  
  196. /*
  197. ** AH = 0x3B
  198. ** DS:DX name (64 bytes)
  199. */
  200. int rm_chdir(char *name)
  201. {
  202.     TRANSLATION ts;
  203.  
  204.     LV_WORD ts.eax = 0x3B00;
  205.     SET_SEG_OFF(name, ts.ds, ts.edx);
  206.     return call_rm_dos(&ts);
  207. }
  208.  
  209. /*
  210. ** AH = 0x43 ; AL = 0
  211. ** DS:DX name
  212. ** return CX: attr
  213. */
  214. int rm_getfattr(char *name, WORD * attr)
  215. {
  216.     TRANSLATION ts;
  217.  
  218.     LV_WORD ts.eax = 0x4300;
  219.     SET_SEG_OFF(name, ts.ds, ts.edx);
  220.     if (call_rm_dos(&ts) == -1)
  221.     return -1;
  222.     else {
  223.     *attr = (WORD) ts.ecx;
  224.     return 0;
  225.     }
  226. }
  227.  
  228. int rm_access(char *name, WORD mode)
  229. {
  230.     WORD attr;
  231.  
  232.     if (rm_getfattr(name, &attr) == -1)
  233.     return -1;
  234.     if ((attr & 1) && (mode & 2))    /* RDONLY and try WRITE access */
  235.     return -1;
  236.     else
  237.     return 0;
  238. }
  239.  
  240. /*
  241. ** AH = 0x43 ; AL = 1
  242. ** CX = attr
  243. ** DS:DX name
  244. */
  245. int rm_setfattr(char *name, WORD attr)
  246. {
  247.     TRANSLATION ts;
  248.  
  249.     LV_WORD ts.eax = 0x4301;
  250.     LV_WORD ts.ecx = attr;
  251.     SET_SEG_OFF(name, ts.ds, ts.edx);
  252.     return call_rm_dos(&ts);
  253. }
  254.  
  255. /*
  256. ** AH = 0x47
  257. ** DS:SI name
  258. */
  259. int rm_getcwd(WORD drive, char *name)
  260. {
  261.     TRANSLATION ts;
  262.  
  263.     LV_WORD ts.eax = 0x4700;
  264.     LV_WORD ts.edx = drive;
  265.     SET_SEG_OFF(name, ts.ds, ts.esi);
  266.     return call_rm_dos(&ts);
  267. }
  268.  
  269. /*
  270. ** AH = 0x4E
  271. ** CX = attr
  272. ** DS:DX name
  273. */
  274. int rm_findfirst(char *name, WORD attr, struct find_t * ft)
  275. {
  276.     TRANSLATION ts;
  277.  
  278.     rm_setdta(ft);
  279.     LV_WORD ts.eax = 0x4E00;
  280.     LV_WORD ts.ecx = attr;
  281.     SET_SEG_OFF(name, ts.ds, ts.edx);
  282.     return call_rm_dos(&ts);
  283. }
  284.  
  285. /* ********** FILE HANDLE OPERATIONS ********** */
  286.  
  287. /*
  288. ** AH = 0x3C
  289. ** CX = attr
  290. ** DS:DX = name
  291. ** return: AX fileno
  292. */
  293. int rm_creat(char *name, WORD attr)
  294. {
  295.     TRANSLATION ts;
  296.  
  297.     LV_WORD ts.eax = 0x3C00;
  298.     LV_WORD ts.ecx = attr;
  299.     SET_SEG_OFF(name, ts.ds, ts.edx);
  300.     return call_rm_dos(&ts);
  301. }
  302.  
  303. /*
  304. ** AH = 0x3D
  305. ** AL = mode
  306. ** DS:DX = name
  307. ** return: AX fileno
  308. */
  309. int rm_open(char *name, WORD modes)
  310. {
  311.     TRANSLATION ts;
  312.  
  313.     LV_WORD ts.eax = 0x3D00 | modes;
  314.     SET_SEG_OFF(name, ts.ds, ts.edx);
  315.     return call_rm_dos(&ts);
  316. }
  317.  
  318. /*
  319. ** AH = 0x3E
  320. ** BX = file handle
  321. ** return: -1 on error
  322. */
  323. int rm_close(WORD handle)
  324. {
  325.     TRANSLATION ts;
  326.  
  327.     LV_WORD ts.eax = 0x3E00;
  328.     LV_WORD ts.ebx = handle;
  329.     if (call_rm_dos(&ts) == -1)
  330.     return -1;
  331.     else
  332.     return 0;
  333. }
  334.  
  335. /*
  336. ** AH = 0x3F
  337. ** BX = handle
  338. ** CX = bytes
  339. ** DS:DX = buf
  340. ** return: AX bytes
  341. */
  342. int rm_read(WORD handle, void *buf, WORD bytes)
  343. {
  344.     TRANSLATION ts;
  345.  
  346.     LV_WORD ts.eax = 0x3F00;
  347.     LV_WORD ts.ebx = (WORD) handle;
  348.     LV_WORD ts.ecx = (WORD) bytes;
  349.     SET_SEG_OFF(buf, ts.ds, ts.edx);
  350.     return call_rm_dos(&ts);
  351. }
  352.  
  353. /*
  354. ** AH = 0x40
  355. ** BX = handle
  356. ** CX = bytes
  357. ** DS:DX = buf
  358. ** return: AX bytes
  359. */
  360. int rm_write(WORD handle, void *buf, WORD bytes)
  361. {
  362.     TRANSLATION ts;
  363.  
  364.     LV_WORD ts.eax = 0x4000;
  365.     LV_WORD ts.ebx = (WORD) handle;
  366.     LV_WORD ts.ecx = (WORD) bytes;
  367.     SET_SEG_OFF(buf, ts.ds, ts.edx);
  368.     return call_rm_dos(&ts);
  369. }
  370.  
  371. /*
  372. ** AH = 0x42
  373. ** AL = orgin
  374. ** BX = handle
  375. ** CX:DX = pos
  376. ** return: new pos
  377. */
  378. long rm_lseek(WORD handle, DWORD offset, WORD orgin)
  379. {
  380.     TRANSLATION ts;
  381.  
  382.     LV_WORD ts.eax = 0x4200 | orgin;
  383.     LV_WORD ts.ebx = (WORD) handle;
  384.     LV_WORD ts.ecx = (WORD) (offset >> 16);
  385.     LV_WORD ts.edx = (WORD) offset;
  386.     if (call_rm_dos(&ts) == -1)
  387.     return -1L;
  388.     else
  389.     return (ts.edx << 16) | (ts.eax & 0xFFFF);
  390. }
  391.  
  392. /*
  393. ** AH = 0x45
  394. ** BX = handle
  395. ** return: AX new handle
  396. */
  397. int rm_dup(WORD handle)
  398. {
  399.     TRANSLATION ts;
  400.  
  401.     LV_WORD ts.eax = 0x4500;
  402.     LV_WORD ts.ebx = handle;
  403.     return call_rm_dos(&ts);
  404. }
  405.  
  406. /*
  407. ** AH = 0x46
  408. ** BX = handle
  409. ** CX = new handle
  410. ** return: -1 on error
  411. */
  412. int rm_dup2(WORD handle, WORD newhandle)
  413. {
  414.     TRANSLATION ts;
  415.  
  416.     LV_WORD ts.eax = 0x4600;
  417.     LV_WORD ts.ebx = handle;
  418.     LV_WORD ts.ecx = newhandle;
  419.     return call_rm_dos(&ts);
  420. }
  421.  
  422. /*
  423. ** AX = 0x5700
  424. ** BX = handle
  425. ** return: CX:DX
  426. */
  427. int rm_getftime(WORD handle, WORD * date, WORD * time)
  428. {
  429.     TRANSLATION ts;
  430.  
  431.     LV_WORD ts.eax = 0x5700;
  432.     LV_WORD ts.ebx = handle;
  433.     if (call_rm_dos(&ts) == -1)
  434.     return -1;
  435.     else {
  436.     *date = (WORD) ts.edx;
  437.     *time = (WORD) ts.ecx;
  438.     return 0;
  439.     }
  440. }
  441.  
  442. /*
  443. ** AX = 0x5701
  444. ** BX = handle
  445. ** CX:DX = time/date
  446. */
  447. int rm_setftime(WORD handle, WORD date, WORD time)
  448. {
  449.     TRANSLATION ts;
  450.  
  451.     LV_WORD ts.eax = 0x5701;
  452.     LV_WORD ts.ebx = handle;
  453.     LV_WORD ts.ecx = time;
  454.     LV_WORD ts.edx = date;
  455.     return call_rm_dos(&ts);
  456. }
  457.  
  458. /*
  459. ** AH = 0x5B
  460. ** CX = attr
  461. ** DS:DX = name
  462. ** return: AX fileno
  463. */
  464. int rm_creatnew(char *name, WORD attr)
  465. {
  466.     TRANSLATION ts;
  467.  
  468.     LV_WORD ts.eax = 0x5B00;
  469.     LV_WORD ts.ecx = attr;
  470.     SET_SEG_OFF(name, ts.ds, ts.edx);
  471.     return call_rm_dos(&ts);
  472. }
  473.  
  474. /*
  475. ** AX = 0x67
  476. ** BX = handles
  477. */
  478. int rm_sethandles(WORD handles)
  479. {
  480.     TRANSLATION ts;
  481.  
  482.     LV_WORD ts.eax = 0x6700;
  483.     LV_WORD ts.ebx = handles;
  484.     return call_rm_dos(&ts);
  485. }
  486.  
  487. /* ********** IOCTL OPERATIONS ********** */
  488.  
  489. /*
  490. ** AH = 0x44 ; AL = 0
  491. ** BX = handle
  492. */
  493. int rm_ioctl_getattr(WORD handle)
  494. {
  495.     TRANSLATION ts;
  496.  
  497.     LV_WORD ts.eax = 0x4400;
  498.     LV_WORD ts.ebx = handle;
  499.     if (call_rm_dos(&ts) == -1)
  500.     return -1;
  501.     else
  502.     return (WORD) ts.edx;
  503. }
  504.  
  505. int rm_isatty(WORD handle)
  506. {
  507.     int i = rm_ioctl_getattr(handle);
  508.     if (i == -1)
  509.     return 0;
  510.     else
  511.     return i & 128;
  512. }
  513.  
  514. /*
  515. ** AH = 0x44 ; AL = 01
  516. ** BX = handle
  517. ** DX = mode
  518. */
  519. int rm_ioctl_setattr(WORD handle, WORD mode)
  520. {
  521.     TRANSLATION ts;
  522.  
  523.     LV_WORD ts.eax = 0x4401;
  524.     LV_WORD ts.ebx = handle;
  525.     LV_WORD ts.edx = mode;
  526.     if (call_rm_dos(&ts) == -1)
  527.     return -1;
  528.     else
  529.     return 0;
  530. }
  531.  
  532. /*
  533. ** AH = 0x44 ; AL = 06
  534. ** BX = handle
  535. */
  536. int rm_ioctl_select_in(WORD handle)
  537. {
  538.     TRANSLATION ts;
  539.  
  540.     LV_WORD ts.eax = 0x4406;
  541.     LV_WORD ts.ebx = handle;
  542.     if (call_rm_dos(&ts) == -1)
  543.     return 0;
  544.     return ((BYTE)ts.eax == 0xFF) ? 1 : 0;
  545. }
  546.  
  547. /*
  548. ** AH = 0x44 ; AL = 09
  549. ** BL = drive
  550. ** ret: 1/0 remote or -1
  551. */
  552. int rm_ioctl_remotedrive(BYTE drive)
  553. {
  554.     TRANSLATION ts;
  555.  
  556.     LV_WORD ts.eax = (WORD) 0x4409;
  557.     LV_WORD ts.ebx = (WORD) drive;
  558.     if (call_rm_dos(&ts) == -1)
  559.     return -1;
  560.     else
  561.     return (int) (ts.edx & 0x1000) >> 12;
  562. }
  563.  
  564. /* ********** PROCESS CONTROL ********** */
  565.  
  566. /*
  567. ** AX = 0x4B00
  568. ** DS:DX = name
  569. ** ES:BX = exec block
  570. ** ret: -1 on error
  571. */
  572. int rm_exec(char *name, struct execb * eb)
  573. {
  574.     TRANSLATION ts;
  575.  
  576.     LV_WORD ts.eax = 0x4B00;
  577.     SET_SEG_OFF(name, ts.ds, ts.edx);
  578.     SET_SEG_OFF(eb, ts.es, ts.ebx);
  579.     return call_rm_dos(&ts);
  580. }
  581.  
  582. /*
  583. ** AX = 0x4D00
  584. ** ret: exit value
  585. */
  586. int rm_get_exit_status(void)
  587. {
  588.     TRANSLATION ts;
  589.  
  590.     LV_WORD ts.eax = 0x4D00;
  591.     return call_rm_dos(&ts);
  592. }
  593.